<?php

namespace Console\Supports;

use Cron\CronExpression;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\PhpExecutableFinder;
use Symfony\Component\Process\Process;

class CronJobScheduler extends Command
{
    protected static $defaultName = 'schedule:run';

    private $command;

    protected function configure()
    {
        $this->setDescription('运行定时任务调度命令');
    }

    public function execute(InputInterface $input, OutputInterface $output)
    {

        $this->command('customize:demo')->expression('* * * * *');
        $this->command('customize:test')->expression('* * * * *');

        return 0;
    }

    private function command(string $command): CronJobScheduler
    {
        if (strpos($command, ' ') !== false) {
            $tempCommand = $command;
            $command = substr($command, 0, strpos($command, ' '));
        }
        $isExist = $this->getApplication()->has($command);
        if ($isExist === true) {
            if (isset($tempCommand)) {
                $this->command = $tempCommand;
            } else {
                $this->command = $command;
            }
        } else {
            $this->command = '';
        }
        return $this;
    }

    private function expression(string $expression): bool
    {
        if ($this->command == '') {
            return false;
        }
        if (!CronExpression::isValidExpression($expression)) {
            return false;
        }

        $cron = new CronExpression($expression);
        $nextTime = $cron->getNextRunDate()->getTimestamp();
        $nowTime = time();
        if ($nextTime <= $nowTime) {
            return false;
        }
        if (($nextTime - $nowTime) > 60) {
            return false;
        }

        $this->doRun();

        return true;
    }

    private function doRun()
    {
        $phpBinaryFinder = new PhpExecutableFinder();

        $command = array(
            $phpBinaryFinder->find(),
            ROOT_PATH . 'cmc',
        );

        if (strpos($this->command, ' ') === false) {
            $command[] = $this->command;
        } else {
            $command = array_merge($command, explode(' ', $this->command));
        }

        $process = new Process($command);
        $env = $_ENV;
        unset($_ENV['database'], $_ENV['redis']);
        $process->start();
        $_ENV = $env;
        $iterator = $process->getIterator($process::ITER_SKIP_ERR | $process::ITER_KEEP_OUTPUT);
        foreach ($iterator as $v) {
            echo $v;
        }
    }
}
